﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using NPOI.SS.Util;

namespace SmartExporter
{
    /// <summary>
    /// 导出对应的Excel
    /// </summary>
    public class ExportUtil
    {
        public delegate void ProgressChangedDelegate(int i,string msg);
        /// <summary>
        /// 导出进度变化的通知
        /// </summary>
        public ProgressChangedDelegate ProgressChanged;

        public delegate void ProgressCompletedDelegate(bool compliete,Exception msg);
        /// <summary>
        /// 导出完成后的事件通知
        /// </summary>
        public ProgressCompletedDelegate ProgressCompleted;
        public BackgroundWorker backgroundWoker {get; private set;}
        public ExportUtil()
        {
            backgroundWoker = new BackgroundWorker();
            backgroundWoker.ProgressChanged += (sender, args) =>
            {
                ProgressChanged?.Invoke(args.ProgressPercentage,args.UserState.ToString());
            };
            backgroundWoker.WorkerReportsProgress = true;
            backgroundWoker.RunWorkerCompleted += (sender, args) =>
            {
                ProgressCompleted?.Invoke((bool) args.Result, args.Error);
            };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath">包含文件名的文件路径，绝对路径，相对路径暂不支持</param>
        /// <param name="list"></param>
        public void ExportAsync<T>(string filePath,List<T> list,double Total)
        {
            if (list == null || list.Count == 0) return;
            if (string.IsNullOrEmpty(filePath)) return;
            var type = typeof(T);
            backgroundWoker.DoWork += (a, b) =>
            {
                try
                {
                    BackgroundWoker_DoWork<T>(filePath, list, Total);
                    b.Result = true;
                }
                catch (Exception e)
                {
                    b.Result = false;
                    throw;
                }

            };
            backgroundWoker.RunWorkerAsync();
        }

        private void BackgroundWoker_DoWork<T>(string filePath,List<T> list,double Total)
        {
            #region 处理表头
            var propDic = new Dictionary<string, string>();
            var propList = new List<ExcelDisplayInfo>();
            var type = typeof(T);
            foreach (var m in type.GetProperties())
            {
                foreach (Attribute a in m.GetCustomAttributes(true))
                {
                    if (a is ExcelDisplayInfo dbi)
                    {
                        if (null != dbi)
                        {
                            propDic.Add(dbi.Name, m.Name);
                            propList.Add(dbi);
                        }
                    }
                }
            }
            
            //var array = (from items in propList orderby items.ExportIndex select items.Name).ToArray();

            #endregion

            var hssfWorkbook = new HSSFWorkbook();
            var sheet = (HSSFSheet)hssfWorkbook.CreateSheet("sheet1");
            var cellStyle = hssfWorkbook.CreateCellStyle();
            cellStyle.Alignment = HorizontalAlignment.Center;
            cellStyle.VerticalAlignment = VerticalAlignment.Center;
            var header = (HSSFRow)sheet.CreateRow(0);
            var array = propDic.Keys.ToArray();
            for (int i = 0; i < array.Length; i++)
            {
                 var cell = header.CreateCell(i);
                    cell.SetCellValue(array[i]);
                    cell.CellStyle = cellStyle;
            }
            backgroundWoker?.ReportProgress(1,"初始化列名");
            FileHelper.CheckPath(filePath);
            for (int i = 0; i < list.Count; i++)
            {
                var rowsCount = (double)i / list.Count;
                backgroundWoker?.ReportProgress(rowsCount > 100 ? 100 : (int)(rowsCount * 100), $"正在填充第{i}行数据，共{list.Count}行数据。");
                var item = list[i];
                var row = (HSSFRow)sheet.CreateRow(i + 1);
                for (int j = 0; j < array.Length; j++)
                {
                    var cell = row.CreateCell(j);
                    var prop = item.GetType().GetProperty(propDic[array[j]]);
                    if (prop == null) continue;
                    string valueCell = "";
                    //判断，如果是时间格式，则设置为空
                    if (prop.PropertyType.Name== "DateTime" && prop.GetValue(item)?.ToString() == "0001-01-01 00:00:00")
                    {
                        valueCell = "";
                    }
                    else
                    {
                        valueCell = prop.GetValue(item)?.ToString();
                    }

                    #region 特殊字段处理
                    //1. 发货单位、货物名称 
                    if (array[j] == "Company")
                    {
                        var prop_1 = item.GetType().GetProperty("SendCptName");
                        if (prop_1 == null) continue;
                        if (!string.IsNullOrEmpty(prop_1.GetValue(item)?.ToString()))
                        {
                            valueCell = prop_1.GetValue(item)?.ToString();
                        }
                    }
                    if (array[j] == "GoodsName")
                    {
                        var prop_1 = item.GetType().GetProperty("MultipleGoodsName");
                        if (prop_1 == null) continue;
                        if (!string.IsNullOrEmpty(prop_1.GetValue(item)?.ToString()))
                        {
                            valueCell = prop_1.GetValue(item)?.ToString();
                        }
                    }
                    //损坏禁用、未使用、入场录入信息、出厂已归还
                    //2. 字段解析转换
                    if (array[j] == "CardStatus")
                    {
                        switch (valueCell)
                        {
                            case "1":
                                valueCell = "入场录入信息";
                                break;
                            case "2":
                                valueCell = "出厂已归还";
                                break;
                            case "-1":
                                valueCell = "损坏禁用";
                                break;
                            case "0":
                                valueCell = "未使用";
                                break;
                        }
                    }
                    if (array[j] == "CardType")
                    {
                        switch (valueCell)
                        {
                            case "1":
                                valueCell = "入厂货物制卡";
                                break;
                            case "2":
                                valueCell = "出厂货物制卡";
                                break;
                        }
                    }
                    #endregion
                    cell.SetCellValue(valueCell);
                    cell.CellStyle = cellStyle;
                }
            }
            //做个统计

            //var lastRow2 = (HSSFRow)sheet.CreateRow(list.Count + 2);
            //var cell12 = lastRow2.CreateCell(0);
            //cell12.SetCellValue("总重量：");
            //cell12.CellStyle = cellStyle;
            //var cell21 = lastRow2.CreateCell(1);
            //cell21.SetCellValue(Total.ToString() + "kg");
            //CellRangeAddress region2 = new CellRangeAddress(list.Count + 2, list.Count + 2, 1, array.Length -1);
            //sheet.AddMergedRegion(region2);
            //cell21.CellStyle = cellStyle;

            backgroundWoker?.ReportProgress(100,"正在合并文件，请稍后。。。");
            var file = new FileStream(filePath,FileMode.Create);
            hssfWorkbook.Write(file);
            file.Close();
        }
    }
}
